codeforces 255D


给出矩形尺寸和初始坐标以及需要的格子数,求时间。
codeforces 255D

对于递增或递减的数据求中间状态,一般二分。
切分方法比较机智,如下。

对于梯状体和矩形相交的考虑还是比较好想的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

#include <cstdio>
#include <cmath>
#include <cstring>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
#define debug puts("-----")
#define maxn 10000+6
#define NV 10000
#define NE 100000
#define LL unsigned long long
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf (1<<30)-4000
#define INF (1ll<<62)
#define mp make_pair
LL n,x,y,c;
LL cnt(LL a,LL b,LL t)
{

if(t>a+b)return a*b;
return t*(t+1)/2-(t>a?(t-a)*(t-a+1)/2:0)-(t>b?(t-b)*(t-b+1)/2:0);
}
LL f(LL t)
{

LL ret=1LL;
ret+=cnt(n-x,n-y+1,t);
ret+=cnt(n-x+1,y-1,t);
ret+=cnt(x-1,y,t);
ret+=cnt(x,n-y,t);
return ret;
}
int main()
{

scanf("%I64u%I64u%I64u%I64u",&n,&x,&y,&c);
LL l=0,r=n*n,m=0;
LL ans=0;
if(c==1)return puts("0"),0;
while(l<=r)
{
m=(l+r)/2;
if(f(m)<c)l=m+1;
else ans=m,r=m-1;
}
printf("%I64u\n",ans);
}

EOF